package 中等.搜索.广度优先搜索;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * 在给定的 m x n 网格 grid 中，每个单元格可以有以下三个值之一：
 * 值 0 代表空单元格；
 * 值 1 代表新鲜橘子；
 * 值 2 代表腐烂的橘子。
 * 每分钟，腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
 * 返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能，返回 -1 。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/rotting-oranges
 */
public class 腐烂的橘子_994 {

    public static void main(String[] args) {

    }

    /**
     * 广度搜索
     *
     * @param grid
     * @return
     */
    public int orangesRotting(int[][] grid) {
        int rows = grid.length, columns = grid[0].length;
        int count = -1;
        int fresh = 0;
        int rotting = 0;
        int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        Deque<int[]> queue = new ArrayDeque<>();
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (grid[i][j] == 2) {
                    queue.addLast(new int[]{i, j});
                }
                if (grid[i][j] == 1) {
                    fresh++;
                }
            }
        }

        while (!queue.isEmpty()) {
            int size = queue.size();
            count++;
            while (size-- > 0) {
                int[] cur = queue.pollFirst();
                for (int[] direct : direction) {
                    int x = cur[0] + direct[0];
                    int y = cur[1] + direct[1];
                    if (x >= 0 && x < rows && y >= 0 && y < columns && grid[x][y] == 1) {
                        rotting++;
                        grid[x][y] = 2;
                        queue.addLast(new int[]{x, y});
                    }
                }
            }
        }

        return rotting == fresh ? Math.max(0, count) : -1;
    }

}
